<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>

</html>
<script>
    // 设计模式：在已有js语法的基础上，进行语法整合，形成固定用法，每种设计模式都是为了解决某种问题
    // 其他模式：工厂模式，目的是为了批量创建对象
    // 单例模式：一个类只能产生一个对象
    var SingleTon = (function () {
        function Tank() {
            this.dom = null;
            this.speed = 0;
            this.color = '';
            this.run = function () { }
        }
        var instance = null;
        return {
            getInstance() {
                return instance || (instance == Tank())
            }
        }
    })()
    var a = SingleTon.getInstance()
    var b = SingleTon.getInstance()
    console.log(a);
    console.log(a == b);


    // 发布订阅模式(观察者模式)
    // 是一对多的关系，多个订阅者监听某一个对象状态（发布者）的变化
        function Observer(){
            this.obj={}
            // 订阅消息
            this.on=function(type,handler){
                this.obj[type]=this.obj[type] || [];
                this.obj[type].push(handler)
            }
            // 发布消息
            this.emit=function(type,msg){
                // 拿到type对应的类型消息所有订阅者的回调函数，调用该函数并将消息传给订阅者
                // if(this.obj[type]){
                //     this.obj[type].forEach((item)=>{
                //         item(msg)
                //     })
                // }
                this.obj[type]&&this.obj[type].forEach((item)=>{
                    item(msg)
                })
            }
            // 暴露函数在外部
            window.Observer=Observer
        }

    var os=new Observer()
    // 订阅消息
    os.on("草莓狸",function(msg){
        console.log('张三收到了来自草莓狸的消息：'+msg);
    })
    os.on("草莓狸",function(msg){
        console.log('二哈收到了来自草莓狸的消息：'+msg);
    })
    os.on("草莓狸",function(msg){
        console.log('卤蛋收到了来自草莓狸的消息：'+msg);
    })
    os.on("草莓狸",function(msg){
        console.log('小米收到了来自草莓狸的消息：'+msg);
    })
    os.on("UU",function(msg){
        console.log("大爷收到了来自UU的消息："+msg);
    })
    // 发布消息
    os.emit("草莓狸",'永劫开播!')
    os.emit("UU","谢谢大爷送的华子!")

    function dy() {
        // 定义一个新对象
        this.obj = {}
        // 订阅消息
        // 第一个参数：消息类型（string类型）
        // 第二个参数：接收消息的函数
        this.on = function (type, handler) {
            this.obj[type] = this.obj[type] || [];
            this.obj[type].push(handler)
        }
        // 发布消息
        this.emit = function (type, msg) {
            this.obj[type] && this.obj[type].forEach((item) => {
                item(msg)
            })
        }

        window.dy = dy
    }
    let c = new dy()
    // 订阅消息
    c.on("Theshy", function (msg) {
        console.log('二狗收到来自Theshy直播间订阅消息：' + msg);
    })
    // 发布消息
    c.emit("Theshy", '别吃别吃别吃！')




    class Publiser {
        constructor() {
            this.wathers = []
        }
        add(info) {
            this.wathers.push(info)
        }
        // 发布消息，参数是消息内容
        notify(what) {
            this.wathers.forEach(item => {
                item.update(what)
            })
        }
    }
    // 收到消息
    class Wathers {
        constructor(name) {
            this.name = name
        }
        update(what) {
            console.log(this.name + "收到订阅消息" + what);
        }
    }
    // 产生发布者，订阅者实例对象
    let pm = new Publiser()
    let xx = new Wathers("张某")
    let xc = new Wathers("二某")
    let xv = new Wathers("杨某")
    let xa = new Wathers("王某")
    let xs = new Wathers("黄某")
    let xd = new Wathers("嘿某")
    pm.add(xx)
    pm.add(xc)
    pm.add(xv)
    pm.add(xa)
    pm.add(xs)
    pm.add(xd)
    pm.notify("疯狂星期四!")
</script>